'''
测试监听鼠标键盘
'''

import pynput
import time
from collections import deque
import json


class Listener(object):
    def __init__(self):
        self.option_log = deque([])
        self.listener1 = pynput.mouse.Listener(
            on_click = self.on_click,
            on_move = self.on_move,
            on_scroll = self.on_scroll
        )
        self.listener2 = pynput.keyboard.Listener(
            on_press = self.on_press,
            on_release = self.on_release
        )

    def getEventObj(self, _time, _type, name, value):
        return {
            'time' : _time, # 动作事件
            'type' : _type, # 动作类型
            'name' : name, # 事件名称
            'value' : value, # 值
        }

    def on_move(self, x, y):
        eventObj = self.getEventObj(time.time(), "mouse", "move", (x, y))
        self.option_log.append(eventObj)
        print('{0} ==> Pointer moved to:{1}'.format(time.time(), (x, y)))


    def on_click(self, x, y, button, pressed):
        if pressed is True:
            eventObj = self.getEventObj(time.time(), "mouse", "press", button.name)
            self.option_log.append(eventObj)
            print('{0} ==> {1} click at {2}'.format(time.time(), button, (x, y)))
        else:
            eventObj = self.getEventObj(time.time(), "mouse", "release", button.name)
            self.option_log.append(eventObj)
            print('{0} ==> {1} release at {2}'.format(time.time(), button, (x, y)))


    def on_scroll(self, x, y, dx, dy):
        eventObj = self.getEventObj(time.time(), "mouse", "scroll", (dx, dy))
        self.option_log.append(eventObj)
        print('point: (x = {0}, y = {1}), scroll: (dx = {2}, dy = {3})'.format(x, y, dx, dy))


    def on_press(self, key):
        if(key == pynput.keyboard.Key.esc):
            # Stop listener
            # for line in option_log:
            #     print(line)
            self.listener1.stop()
            self.listener2.stop()
            self.save()
            return False
            
        try:
            c = key.char # 字符按键
            eventObj = self.getEventObj(time.time(), "keyboard", "press", (c, key.vk))
            self.option_log.append(eventObj)
            print('char key {0} pressed'.format((c, key.vk)))
        except AttributeError:
            eventObj = self.getEventObj(time.time(), "keyboard", "press", (key.name, key.value.vk))
            self.option_log.append(eventObj)
            print('special key {0} pressed'.format((key.name, key.value.vk)))


    def on_release(self, key):
        try:
            c = key.char # 字符按键
            eventObj = self.getEventObj(time.time(), "keyboard", "release", (c, key.vk))
            self.option_log.append(eventObj)
            print('char key {0} pressed'.format((c, key.vk)))
        except AttributeError:
            eventObj = self.getEventObj(time.time(), "keyboard", "release", (key.name, key.value.vk))
            self.option_log.append(eventObj)
            print('special key {0} pressed'.format((key.name, key.value.vk)))


    def save(self):
        with open('./record.txt', 'a', encoding='utf-8') as f:
            for line in self.option_log:
                f.writelines(json.dumps(line) + '\n')
                pass
            f.flush()


    def start(self):
        self.listener1.start()
        self.listener2.start()
        self.listener1.join()
        self.listener2.join()


# with pynput.mouse.Listener(
#     on_click = on_click,
#     on_move = on_move,
#     on_scroll = on_scroll
#     ) as listener:
#     listener.join()


# with pynput.keyboard.Listener(
#     on_press = on_press,
#     on_release = on_release
# ) as listener:
#     listener.join()


if __name__ == '__main__':
    Listener().start()
